package mymyoux.io.sockets.servers
{
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.ServerSocketConnectEvent;
	import flash.net.ServerSocket;
	
	import mymyoux.debug.log;
	
	import mymyoux.signals.Signal;
	import mymyoux.io.sockets.ISocket;
	import mymyoux.io.sockets.clients.BinarySocket;
	public class BinaryServerSocket implements ISocket
	{
		protected var _serverSocket:ServerSocket;
		private var _port:uint;
		private var _host:String;
		/**
		 * @private
		 */
		private var _signalStatus:Signal;
		private var _signalError:Signal;
		private var _securityXML:String="<?xml version=\"1.0\"?>\n<!DOCTYPE cross-domain-policy SYSTEM \"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\">\n<cross-domain-policy>\n<allow-access-from domain=\"%domain%\" to-ports=\"%ports%\"/>\n</cross-domain-policy>";
		public function BinaryServerSocket()
		{
			_host = "0.0.0.0";
			_port = 0;
			_serverSocket = new ServerSocket();
			_serverSocket.addEventListener(ServerSocketConnectEvent.CONNECT, onConnect);
			_serverSocket.addEventListener(Event.CLOSE, onClose);
			//signals
			_signalStatus = new Signal(ISocket, Boolean);
			_signalError = new Signal(BinaryServerSocket, ErrorEvent);
		}
		public function get host():String
		{
			return _host;
		}
		public function set host(value:String):void
		{
			if(value != null && value.length > 0)
			{
				_host = value;
			}
		}
		public function get port():uint
		{
			return _port;
		}
		public function set port(value:uint):void
		{
			if(value >= 0 || value <= 65535)
			{
				_port = value;
			}
		}
		public function get signalData():Signal
		{
			return null;
		}
		public function get signalError():Signal
		{
			return _signalError;
		}
		public function get signalStatus():Signal
		{
			return _signalStatus;
		}
		public function connect():void
		{
			try
			{
				_serverSocket.bind(port,  host);
				_serverSocket.listen();
				_securityXML = _securityXML.replace("%domain%", "*").replace("%ports%", port);
			}
			catch(error:Error)
			{
				trace("Error[BinaryServer]:"+error);
				signalError.dispatch(this, new ErrorEvent(error.message));
			}
		}
		public function get securityPolicyFile():String
		{
			return _securityXML.replace("%domain%", "*").replace("%ports%", port);
		}
		public function set securityPolicyFile(value:String):void
		{
			_securityXML = value;
		}
		protected function onClose(event:Event):void
		{
			signalStatus.dispatch(this, false);
		}
		protected function onConnect(event:ServerSocketConnectEvent):void
		{
			var socket:BinarySocket = new BinarySocket();
			socket.socket = event.socket;
			socket.signalPolicy.addOnce(onSecurityPolicyRequest);
			signalStatus.dispatch(socket, true);
			//_serverSocket.close();
		}
		protected function onSecurityPolicyRequest(socket:BinarySocket):void
		{
			//log(_securityXML);
			socket.socket.writeUTFBytes(_securityXML);
			socket.socket.flush();
			socket.close();
		}

	}
}